import os
import wave
from musicClassify.project.musicClassify import config
import numpy
import keras


def Read_WAV(wav_path):
    """
    这是读取wav文件的函数，音频数据是单通道的。返回json
    :param wav_path: WAV文件的地址
    """
    wav_file = wave.open(wav_path, 'rb')
    numchannel = wav_file.getnchannels()  # 声道数
    samplewidth = wav_file.getsampwidth()  # 量化位数
    framerate = wav_file.getframerate()  # 采样频率
    numframes = wav_file.getnframes()  # 采样点数
    # print("channel", numchannel)
    # print("sample_width", samplewidth)
    # print("framerate", framerate)
    # print("numframes", numframes)
    Wav_Data = wav_file.readframes(numframes)
    Wav_Data = numpy.fromstring(Wav_Data, dtype=numpy.int16)
    Wav_Data = Wav_Data * 1.0 / (max(abs(Wav_Data)))  # 对数据进行归一化
    # 生成音频数据,ndarray不能进行json化，必须转化为list，生成JSON
    dict = {"channel": numchannel,
            "samplewidth": samplewidth,
            "framerate": framerate,
            "numframes": numframes,
            "WaveData": list(Wav_Data)}
    # return json.dumps(dict)
    wav_file.close()
    # 取前一百秒 wav标准44.1k采样频率
    return Wav_Data[0:44000 * config.time * numchannel], numchannel

def loadData(music_path):
    print('---数据加载路径:'+music_path)
    peoplesDir = os.listdir(music_path)
    peoplesDir.remove(".DS_Store")  # 删除mac文件夹下的隐藏文件
    peoplesDir = sorted(peoplesDir)
    peopleSize = len(peoplesDir)

    x_train = []
    y_train = []
    classNum = 0

    '''
    此方法加载出的数据会有块状集合  keras训练时shuffle=True会混洗
    浮点加归一化提高计算速度
    '''
    for peopleDir in peoplesDir:
        peoplePath = os.path.abspath(os.path.join(music_path, peopleDir))
        for picItem in os.listdir(peoplePath):
            picPath = os.path.abspath(os.path.join(peoplePath, picItem))
            if picPath.endswith('.wav'):
                #  [::4]重采样为原来得1/4 数据太大会内存溢出
                data, numchannel = Read_WAV(picPath)
                data = data[::11*numchannel]
                # reshape一维升三维
                x_train.append(numpy.asarray(data).reshape(1000,4*config.time,1))
                y_train.append(numpy.asarray([classNum]))
        classNum = classNum + 1
    x_train = numpy.asarray(x_train)
    y_train = numpy.asarray(y_train)
    # Normalize data.
    # Convert class vectors to binary class matrices.
    y_train = keras.utils.to_categorical(y_train, classNum)
    return classNum, x_train, y_train

# 每个模块都有一个__name__属性，当其值是'__main__'时，表明该模块自身在运行，否则是被引入
if __name__ == '__main__':
    Read_WAV("/Users/mc/Desktop/TF/music/happy/1-17 节日里的洛阳城.wav")
